package com.yellowpage.white.generator;

import java.io.File;
import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.Column;
import javax.persistence.Table;

public class GeneratorSpringHibernate extends AberstractGenerator {

	public void generate() {
		String className = (String)this.properties.get("className");
		String dataPackage = (String)this.properties.get("dataPackage");
		String packageName = (String)this.properties.get("packageName");
		String templatePath = (String)this.properties.get("templatePath");		
		
		String objectName = className.substring(0, 1).toLowerCase()
				+ className.substring(1);
		if (dataPackage == null || dataPackage.length() == 0) {
			dataPackage = packageName + ".data";
		}

		// 初始化Java生成器		
		this.setObject("package", packageName);
		this.setObject("className", className);

		this.setObject("objectName", objectName);
		this.setObject("dataPackage", dataPackage);
		this.setObject("daoPackage", packageName + ".dao");
		this.setObject("servicePackage", packageName + ".service");
		this.setObject("testPackage", packageName + ".test");
		
		this.initFields(dataPackage + "." + className);

		// 处理文件路径
		File tempFile = new File("");
		String realTemplatePath = tempFile.getAbsolutePath() + templatePath
				+ "\\";
		makePackageDir(tempFile.getAbsolutePath() + "\\src", packageName);

		// DAO
		String targetDAOPath = this.getPackageFilePath(tempFile
				.getAbsolutePath()
				+ "\\src\\", packageName + ".dao");

		File daoTempFile = new File(realTemplatePath + "WHITE_DAO.tmp");
		File daoJavaFile = new File(targetDAOPath + className + "Dao.java");
		this.generate(daoTempFile, daoJavaFile);

		File daoImplTempFile = new File(realTemplatePath
				+ "WHITE_DAO_IMPL.tmp");
		File daoImplJavaFile = new File(targetDAOPath + className
				+ "DaoImpl.java");
		this.generate(daoImplTempFile, daoImplJavaFile);

		// Service
		String targetServicePath = this.getPackageFilePath(tempFile
				.getAbsolutePath()
				+ "\\src\\", packageName + ".service");

		File serviceTempFile = new File(realTemplatePath + "WHITE_SERVICE.tmp");
		File serviceJavaFile = new File(targetServicePath + className
				+ "Service.java");
		this.generate(serviceTempFile, serviceJavaFile);

		File serviceImplTempFile = new File(realTemplatePath
				+ "WHITE_SERVICE_IMPL.tmp");
		File serviceImplJavaFile = new File(targetServicePath + className
				+ "ServiceImpl.java");
		this.generate(serviceImplTempFile, serviceImplJavaFile);

		// Test
		String targetTestPath = this.getPackageFilePath(tempFile
				.getAbsolutePath()
				+ "\\src\\", packageName + ".test");

		File daoTestTempFile = new File(realTemplatePath
				+ "WHITE_DAO_TEST.tmp");
		File daoTestJavaFile = new File(targetTestPath + className
				+ "DaoTest.java");
		this.generate(daoTestTempFile, daoTestJavaFile);

		File serviceTestTempFile = new File(realTemplatePath
				+ "WHITE_SERVICE_TEST.tmp");
		File serviceTestJavaFile = new File(targetTestPath + className
				+ "ServiceTest.java");
		this.generate(serviceTestTempFile, serviceTestJavaFile);

		// XML
		String targetXMLPath = this.getPackageFilePath(tempFile
				.getAbsolutePath()
				+ "\\src\\", packageName);

		File xmlTempFile = new File(realTemplatePath + "WHITE_CORE_CONFIG.tmp");
		File xmlFile = new File(targetXMLPath + className + "CoreXML.txt");
		this.generate(xmlTempFile, xmlFile);

	}

	public void makePackageDir(String srcPath, String packageName) {

		String[] packageArray = packageName.split("\\.");

		String currentPath = srcPath;
		for (int i = 0; i < packageArray.length; i++) {
			currentPath = currentPath + "\\" + packageArray[i];
			File tempFile = new File(currentPath);

			if (!tempFile.exists()) {
				System.out.println("创建目录：" + currentPath);
				tempFile.mkdir();
			}
		}

		File daoFile = new File(currentPath + "\\" + "dao");
		if (!daoFile.exists()) {
			System.out.println("创建目录：" + daoFile.getAbsolutePath());

			daoFile.mkdir();
		}

		File serviceFile = new File(currentPath + "\\" + "service");
		if (!serviceFile.exists()) {
			System.out.println("创建目录：" + serviceFile.getAbsolutePath());

			serviceFile.mkdir();
		}

		File testFile = new File(currentPath + "\\" + "test");
		if (!testFile.exists()) {
			System.out.println("创建目录：" + testFile.getAbsolutePath());

			testFile.mkdir();
		}

	}
	
	public void initFields(String dataClass) {
		try{
		    Class dataObjectClass = Class.forName(dataClass);	    
		    
		    String className = dataObjectClass.getName();
		    className = className.substring(className.lastIndexOf('.') + 1);
		    
		    Table table = (Table)dataObjectClass.getAnnotation(Table.class);
		    
		    this.setObject("TableName", table.name());
		    
		    Method[] methods = dataObjectClass.getDeclaredMethods();
		    
		    for (int i=0; i<methods.length; i++) {
		        String methodName = methods[i].getName();
		        Column column = methods[i].getAnnotation(Column.class);				        
		        
		    	if(methodName.startsWith("get")){
		    		String fieldName = methodName.substring(3);
		    		String fieldType = methods[i].getGenericReturnType().toString();
		    		
		    		Map fieldMap = new HashMap();
					fieldMap.put("fieldName", fieldName);
					fieldMap.put("fieldInst", fieldName.substring(0,1).toLowerCase()+ fieldName.substring(1));
					fieldMap.put("fieldType", fieldType.substring(fieldType.lastIndexOf('.') + 1));
										
					if(column != null){
					    fieldMap.put("columnName", column.name());
					}
					
					
					if(fieldName.equals(className + "Id")){
						fieldList.add(0, fieldMap);
					}else{
					    fieldList.add(fieldMap);
					}
		    	}		    	
		    }
		    
		}catch(Exception e){
			e.printStackTrace();
		}	
		this.setObject("fieldList", fieldList);
		
		constractSelectSQL();
	}
	
	private void constractSelectSQL(){
		//查询语句的组成 SELECT [fieldsStr] FROM [table] WHERE [whereStr]
        StringBuffer sqlStr = new StringBuffer("SELECT " +  constructFieldsString(this.fieldList) + " FROM " + this.getObject("TableName") + " a WHERE 1=1 ");
        this.setObject("SelectSQL", sqlStr.toString());
	}
	
	private String constructFieldsString(List fieldList){
        //构造字段语句 [fieldsStr] (" ID, NAME, DESC ")
        StringBuffer fieldsStr = new StringBuffer("");
        if(fieldList != null){
            for(int i = 0; i < fieldList.size(); i++){
            	Map field = (Map)fieldList.get(i);
                fieldsStr.append("a." + field.get("columnName") + " , ");
            }  
            //去除最后一个','
            fieldsStr.setCharAt(fieldsStr.lastIndexOf(","), ' ');
        }else{
            fieldsStr.append("*");
        }
        return fieldsStr.toString();
    }

}
